﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using CommonUtilities;
using CommonUtilities.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MovieBrowser.Model;
using MovieBrowser.Parser;

namespace MovieBrowserTest
{
    [TestClass]
    public class UnitTest1
    {

        [TestMethod]
        public void TestParsePerson()
        {
            ImdbParser.LoadRules("imdb_re.xml");

            var urls = new[] { "http://www.imdb.com/name/nm0000949/" };

            foreach (var url in urls)
            {
                string html = HttpHelper.FetchWebPage(url);

                Person person = ImdbParser.ParsePerson(html);

            }
            Assert.IsTrue(true);
        }

        [TestMethod]
        public void ReadRulesXml()
        {
            var serializer = new XmlSerializer(typeof(ImdbRules));
            TextReader reader = new StreamReader("C:\\Users\\maksud\\Documents\\imdb_re.xml");
            var rules = (ImdbRules)serializer.Deserialize(reader);

            Assert.IsTrue(rules.Rules.Length > 0);

            reader.Close();
        }

        [TestMethod]
        public void WriteRulesXml()
        {
            var serializer = new XmlSerializer(typeof(ImdbRules));
            TextWriter writer = new StreamWriter("C:\\Users\\maksud\\Documents\\imdb_re.xml");
            var rules = new ImdbRules();
            var lrules = new List<ParseRule>();
            ParseRule rule;

            //
            rule = new ParseRule(ImdbParser.Rating, @"<span.+?itemprop=""ratingValue"">([\d.]+)</span>", "$1");
            lrules.Add(rule);

            //(IMDb - )
            rule = new ParseRule
                       {
                           Name = ImdbParser.Title,
                           Pattern = @"<title>(.+?) \(.*?(\d{4}).*?\)",
                           Replacement = "$1",
                           ReplaceText = "(IMDb - )",
                           ReplaceWithText = ""
                       };
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Year, @"<title>(.+?) \(.*?(\d{4}).*?\)", "$2");
            lrules.Add(rule);

            rule = new ParseRule
            {
                Name = ImdbParser.Runtime,
                Pattern = @"Runtime:</h4>\s+(.+?)</div>",
                Replacement = "$1",
                ReplaceText = "(»|<a.*?>|</a>|<time.*?>|</time>|<span class=\"see-more inline\">.+?</span>|<span.*?>|</span>)",
                ReplaceWithText = "",
                Options = RegexOptions.Singleline
            };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.ReleaseDate,
                           Pattern = @"Release Date:</h4>\s+(.+?)</div>",
                           Replacement = "$1",
                           ReplaceText = "(»|<a.*?>|</a>|<time.*?>|</time>|<span class=\"see-more inline\">.+?</span>|<span.*?>|</span>)",
                           ReplaceWithText = "",
                           Options = RegexOptions.Singleline
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Mpaa,
                           Pattern = @"<div class=""infobar"">\s*(<img.+?title=""(.+?)"".+?>)?",
                           Replacement = "$2"
                       };
            lrules.Add(rule);

            rule = new ParseRule
            {
                Name = ImdbParser.MpaaReason,
                Pattern = @"<h4>Motion Picture Rating \(<a.*?href=""/mpaa"".*?>MPAA</a>\)</h4>\s*(.+?)\s*<span",
                Replacement = "$1",
                ReplaceText = "(<span.*?>|</span>)",
                ReplaceWithText = ""
            };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Genres,
                           Pattern = @"href=""/genre/(.+?)"".*?>(.+?)</a>",
                           Options = RegexOptions.Singleline,
                           Replacement = "$1,$2",
                           Separator = ",",
                           IsArray = true
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Languages,
                           Pattern = "href=\"/language/(.+?)\".+?>(.+?)</a>",
                           Options = RegexOptions.Singleline,
                           Replacement = "$1,$2",
                           Separator = ",",
                           IsArray = true
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Countries,
                           Pattern = "href=\"/country/(.+?)\".*?>(.+?)</a>",
                           Options = RegexOptions.Singleline,
                           Replacement = "$1,$2",
                           Separator = ",",
                           IsArray = true
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Persons,
                           Pattern = @"<a.*?href=""/name/(nm[0-9]+)/"".*?>(.+?)</a>",
                           Options = RegexOptions.Singleline,
                           Replacement = "$1,$2",
                           Separator = ",",
                           IsArray = true
                       };
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Stars, @"Stars?:\s*</h4>\s*(.+?)</div>", "$1", RegexOptions.Singleline);
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Writers, @"Writers?:\s*</h4>\s*(.+?)</div>", "$1", RegexOptions.Singleline);
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Directors, @"Directors?:\s*</h4>\s*(.+?)</div>", "$1", RegexOptions.Singleline);
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Actors, @"<table class=""cast_list"">(.+?)</table>", "$1", RegexOptions.Singleline);
            lrules.Add(rule);

            rule = new ParseRule
            {
                Name = ImdbParser.Highlight,
                Pattern = "class=\"article highlighted\" >(.+?)</div>",
                Replacement = "$1",
                ReplaceText = "(»|<em.*?>|</em>|<a.*?>|</a>|<b.*?>|</b>|<div.*?>|</div>|<strong>|</strong>|<span class=\"see-more inline\">.+?</span>|<span.*?>|</span>)",
                ReplaceWithText = "",
                Options = RegexOptions.Singleline
            };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Storyline,
                           Pattern = @"<h2>Storyline</h2>\s*<p>(.+?)</p>",
                           Replacement = "$1",
                           ReplaceText = "(»|<em.*?>|</em>|<a.*?>|</a>|<b.*?>|</b>|<div.*?>|</div>|<strong>|</strong>|<span.*?>|</span>)",
                           ReplaceWithText = "",
                           Options = RegexOptions.Singleline
                       };
            lrules.Add(rule);



            rule = new ParseRule
                       {
                           Name = ImdbParser.Characters,
                           ParentRule = new ParseRule
                                            {
                                                Name = ImdbParser.CharacterRow,
                                                Pattern = @"<tr.*?>(.*?)</tr>",
                                                Replacement = "$1",
                                                Options = RegexOptions.Singleline,
                                                IsArray = true
                                            },
                           Pattern = @"<td class=""name""> <a.*?href=""/name/(nm\d+)/"" >(.+?)</a> </td> <td.+?<td class=""character"">( <div> (<a.+?href=""/character/(ch\d+)/"" >)?(.*?)(</a>.*?)? </div>)?.*?</td>",
                           Replacement = "$1,$2,$5,$6",
                           IsArray = true,
                           Separator = ",",
                           Options = RegexOptions.Singleline
                       };
            lrules.Add(rule);



            rule = new ParseRule
                       {
                           Name = ImdbParser.ImdbId,
                           Pattern =
                               @"<meta property=""og:url"" content=""http://www\.imdb\.com/title/(tt[0-9]+?)/",
                           Replacement = "$1"
                       };
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.Poster, "<td rowspan=\"2\" id=\"img_primary\">.+?<img src=\"(http://.+?)\"", "$1");
            lrules.Add(rule);

            rule = new ParseRule(ImdbParser.MediaFrom, "Media from&nbsp;<a href=\"/title/(tt[0-9]+)/", "$1");
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.Keywords,
                           Pattern = @"<a href=""/keyword/(.+?)/"">(.+?)</a>",
                           IsArray = true,
                           Replacement = "$1,$2",
                           Separator = ","
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = "Guess",
                           Pattern = @"Media from&nbsp;<a href=""/title/(tt[0-9]+)/"".+?>(.+?)</a>(\s*\(([0-9]+?)\))?",
                           IsArray = true,
                           Replacement = "$1,$2,$4"
                       };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           Name = ImdbParser.PersonName,
                           Pattern = "<meta name=\"title\" content=\"(.+?)\" />",
                           Replacement = "$1",
                           ReplaceText = "(IMDb - |- IMDb)",
                           ReplaceWithText = ""
                       };
            lrules.Add(rule);

            rule = new ParseRule
            {
                Name = ImdbParser.PersonId,
                Pattern = @"<meta property=""og:url"" content=""http://www\.imdb\.com/name/(.+?)/"" />",
                Replacement = "$1",
            };
            lrules.Add(rule);

            rule = new ParseRule
            {
                Name = ImdbParser.PersonBirthday,
                Pattern = "<time itemprop=\"birthDate\" datetime=\"(.+?)\">",
                Replacement = "$1",
            };
            lrules.Add(rule);

            rule = new ParseRule
                        {
                            Name = ImdbParser.PersonDeathday,
                            Pattern = "<time itemprop=\"deathDate\" datetime=\"(.+?)\">",
                            Replacement = "$1",
                        };
            lrules.Add(rule);

            rule = new ParseRule
                        {
                            Name = ImdbParser.PersonHeight,
                            Pattern = @"<h4 class=""inline"">Height:</h4>\s*(.+)",
                            Replacement = "$1",
                        };
            lrules.Add(rule);


            rule = new ParseRule
            {
                Name = ImdbParser.PersonBirthplace,
                Pattern = @"<a class=""canwrap"" href=""/search/name\?birth_place=.+?"">(.+?)</a>",
                Replacement = "$1",
            };
            lrules.Add(rule);

            rule = new ParseRule
                       {
                           ParentRule = new ParseRule
                                           {
                                               Name = "InfoBar",
                                               Pattern = "<div class=\"infobar\">(.+?)</div>",
                                               Replacement = "$1",
                                               Options = RegexOptions.Singleline
                                           },
                           Name = ImdbParser.PersonProfession,
                           Pattern = "<a.*?>(.+?)</a>",
                           Replacement = "$1",
                           Options = RegexOptions.Singleline,
                           IsArray = true
                       };
            lrules.Add(rule);

            rules.Rules = lrules.ToArray();
            serializer.Serialize(writer, rules);
            writer.Close();
        }

        [TestMethod]
        public void TestImdbParsing()
        {
            ImdbParser.LoadRules("C:\\Users\\maksud\\Documents\\imdb_re.xml");

            var urls = new[] { "http://www.imdb.com/title/tt0338751/", "http://www.imdb.com/title/tt0338751/" };

            foreach (var url in urls)
            {
                string html = HttpHelper.FetchWebPage(url);

                var Rating = ImdbParser.ParseRating(html);
                var Title = ImdbParser.ParseTitle(html);
                var Year = ImdbParser.ParseYear(html);
                var ImdbId = ImdbParser.ParseId(html);
                var Runtime = ImdbParser.ParseRuntime(html);
                var MPAA = ImdbParser.ParseMpaa(html);
                var MPAAReason = ImdbParser.ParseMpaaReason(html);
                var Highlight = ImdbParser.ParseHighlight(html);
                var ReleaseDate = ImdbParser.ParseReleaseDate(html);
                var Storyline = ImdbParser.ParseStoryline(html);

                var Genres = ImdbParser.ParseGenres(html);
                var Countries = ImdbParser.ParseCountries(html);
                var Languages = ImdbParser.ParseLanguages(html);
                var PersonStars = ImdbParser.ParseStars(html);
                var PersonWriters = ImdbParser.ParseWriters(html);
                var PersonDirectors = ImdbParser.ParseDirectors(html);
                var PersonActors = ImdbParser.ParseActors(html);
            }
            Assert.IsTrue(true);
        }

        [TestMethod]
        public void Test1()
        {
            const string str =
                @"<div class=""article highlighted"" > 
 
    
 
<a href=""http://www.imdb.com/chart/bottom?tt0417056""><strong>Bottom 100 #12</strong></a> 
 
| See 
<a href=""/chart/bottom"">the Bottom 100</a> 
movies as voted by our users.
 
 
 
</div> ";

            string str2 =
                Regex.Match(str, "class=\"article highlighted\" >(.+?)</div>", RegexOptions.Singleline).Groups[1].Value;
            str2 = Regex.Replace(str2, "<span class=\"see-more inline\">.+?</span>", "");

            str2 = Regex.Replace(str2, "<a.*?>(.+?)</a>", "$1");
            str2 = Regex.Replace(str2, "<b.*?>(.+?)</b>", "$1");
            str2 = Regex.Replace(str2, "<strong.*?>(.+?)</strong>", "$1");
            str2 = Regex.Replace(str2, @"\s+", " ");
            str2 = str2.Trim();

            Assert.IsTrue(str2.Length > 0);
        }


        [TestMethod]
        public void Test2()
        {
            string str = @"<h2>Storyline</h2>\s*<p>(.+?)</p>";

            string str2 =
                @"

<div class=""article"" >

    


<span class=""rightcornerlink""><a href=""/register/login?why=edit""
    rel=""login"">Edit</a></span>


<h2>Storyline</h2>

<p>With the world now aware of his dual life as the armored superhero Iron Man, billionaire inventor Tony Stark faces pressure from the government, the press, and the public to share his technology with the military. Unwilling to let go of his invention, Stark, along with Pepper Potts, and James &#x22;Rhodey&#x22; Rhodes at his side, must forge new alliances - and confront powerful enemies.


</p>
<span class=""see-more inline"">
<a href=""plotsummary"">Plot Summary</a>";

            string val = Regex.Match(str2, str).Groups[1].Value;

            val = Regex.Replace(val, "<em.+?</em>", "");

            val = val.Clean();
            val = val.Trim();

            Assert.IsTrue(val.Length > 0);
        }
    }
}